#include<cstdio>//uncle-lu
#include<cstring>
#include<algorithm>
template<class T>void read(T &x)
{
	x=0;int f=0;char ch=getchar();
	while(ch<'0'||ch>'9') { f|=(ch=='-'); ch=getchar(); }
	while(ch<='9'&&ch>='0') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
	x = f ? -x : x;
	return ;
}

int n, m, cnt;
int map[510][510];
int line[250010];
int Father[250010];
int x_turn[4]={1, -1, 0, 0};
int y_turn[4]={0, 0, 1, -1};

int Find_Father(int x)
{
	return Father[x] == x ? x : Father[x] = Find_Father(Father[x]);
}

int turn(int x, int y)
{
	return (x - 1) * m + y;
}

bool check(int x)
{
	for (int i = 1; i <= n*m; i++) 
		Father[i] = i;

	for (int i = 1; i <= n; i++) 
		for (int j = 1; j <= m; j++) 
			for (int k =  0; k <= 3; k++) 
			{
				int xx = i + x_turn[k], yy = j + y_turn[k];
				if(xx < 1 || yy < 1 || xx > n || yy > m)continue;
				if(abs(map[xx][yy] - map[i][j]) > x)continue;
				Father[Find_Father(turn(xx, yy))] = Find_Father(turn(i ,j));
			}

	for (int i = 2; i <= cnt; i++) 
		if(Find_Father(line[i]) != Find_Father(line[i-1]))
			return false;

	return true;
}

int main()
{
	int mx;
	read(n);read(m);
	for (int i = 1; i <= n; i++) 
		for (int j = 1; j <= m; j++) 
			read(map[i][j]), mx = std::max(mx, map[i][j]);

	int temp;
	for (int i = 1; i <= n; i++) 
		for (int j = 1; j <= m; j++) 
		{
			read(temp);
			if(temp)
				line[++cnt] = turn(i, j);
		}

	int l=0, r=mx, mid, ans;
	while(l<=r)
	{
		mid = (l+r)>>1;
		if(check(mid))
		{
			ans = mid;
			r = mid-1;
		}
		else
			l = mid+1;
	}

	printf("%d", ans);

	return 0;
}
